home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / Obrn-A_1.6_lib.lha / oberon-a / source3.lha / source / Library / Strings.mod < prev    next >
Text File  |  1995-06-29  |  5KB  |  219 lines

  1. (***************************************************************************
  2.  
  3.      $RCSfile: Strings.mod $
  4.   Description: String manipulation
  5.  
  6.    Created by: fjc (Frank Copeland)
  7.     $Revision: 1.10 $
  8.       $Author: fjc $
  9.         $Date: 1995/06/04 23:22:41 $
  10.  
  11.   Copyright © 1994, Frank Copeland.
  12.   This file is part of the Oberon-A Library.
  13.   See Oberon-A.doc for conditions of use and distribution.
  14.  
  15. ***************************************************************************)
  16.  
  17. <*$ IndexChk- *>
  18.  
  19. (* Index checking is handled explicitly by the relevant procedures. *)
  20.  
  21. MODULE Strings;
  22.  
  23. IMPORT SYS := SYSTEM;
  24.  
  25.  
  26. PROCEDURE Min ( a, b : INTEGER ) : INTEGER;
  27. BEGIN (* Min *)
  28.   IF a < b THEN RETURN a
  29.   ELSE RETURN b
  30.   END
  31. END Min;
  32.  
  33.  
  34. PROCEDURE Length *
  35.   ( s : ARRAY OF CHAR )
  36.   : INTEGER;
  37.  
  38.   VAR len : INTEGER;
  39.  
  40. <*$CopyArrays-*>
  41. BEGIN (* Length *)
  42.   len := SHORT (SYS.STRLEN (s));
  43.   RETURN Min (SHORT (LEN (s)), len)
  44. END Length;
  45.  
  46.  
  47. PROCEDURE Append *
  48.   ( extra    : ARRAY OF CHAR;
  49.     VAR dest : ARRAY OF CHAR );
  50.  
  51.   VAR max, len1, len2 : INTEGER;
  52.  
  53. <*$CopyArrays-*>
  54. BEGIN (* Append *)
  55.   len1 := Length (dest); max := SHORT (LEN (dest)); DEC (max);
  56.   IF len1 < max THEN
  57.     (* There is actually room at the end of the array. *)
  58.     len2 := Min (len1 + Length (extra), max);
  59.     SYS.MOVE (SYS.ADR (extra), SYS.ADR (dest [len1]), len2 - len1 );
  60.     dest [len2] := 0X;
  61.   END
  62. END Append;
  63.  
  64.  
  65. PROCEDURE Insert *
  66.   ( source   : ARRAY OF CHAR;
  67.     pos      : INTEGER;
  68.     VAR dest : ARRAY OF CHAR );
  69.  
  70.   VAR max, len1, len2 : INTEGER;
  71.  
  72. <*$CopyArrays-*>
  73. BEGIN (* Insert *)
  74.   len1 := Length (source); len2 := Length (dest);
  75.   max := SHORT (LEN (dest)); DEC (max);
  76.   IF (pos >= len2) THEN
  77.     (* The start position is past the end of the target string. *)
  78.     Append (dest, source)
  79.   ELSIF ((len1 + len2) <= max) THEN
  80.     (*
  81.       The result will fit into the target string. Move characters towards
  82.       the end of the string to make room and copy the new characters into
  83.       the space.
  84.     *)
  85.     SYS.MOVE
  86.       ( SYS.ADR (dest [pos]), SYS.ADR (dest [pos + len1]), len2 - pos );
  87.     SYS.MOVE (SYS.ADR (source), SYS.ADR (dest [pos]), len1);
  88.     dest [len2 + len1] := 0X
  89.   ELSIF ((pos + len1) < max) THEN
  90.     (*
  91.       The result will overflow the target string, but the subString will
  92.       fit. Move characters towards the end of the string to make room and
  93.       copy the new characters into the space.
  94.     *)
  95.     SYS.MOVE
  96.       ( SYS.ADR (dest [pos]), SYS.ADR (dest [pos + len1]),
  97.         max - len1 - pos );
  98.     SYS.MOVE ( SYS.ADR (source), SYS.ADR (dest [pos]), len1 );
  99.     dest [max] := 0X
  100.   ELSE
  101.     (*
  102.       The result will overflow the target string, and the subString is too
  103.       long to fit. Just discard the end of the target string and append
  104.       the new characters to it.
  105.     *)
  106.     dest [pos] := 0X; Append (dest, source)
  107.   END
  108. END Insert;
  109.  
  110.  
  111. PROCEDURE Delete *
  112.   ( VAR s  : ARRAY OF CHAR;
  113.     pos, n : INTEGER );
  114.  
  115.   VAR len : INTEGER;
  116.  
  117. BEGIN (* Delete *)
  118.   IF n > 0 THEN
  119.     len := Length (s);
  120.     IF pos < len THEN
  121.       IF (pos + n) < len THEN
  122.         (* Move characters towards the front of the array into the space
  123.         ** deleted.
  124.         *)
  125.         SYS.MOVE
  126.           ( SYS.ADR (s [pos + n]), SYS.ADR (s [pos]), len - (pos + n) );
  127.         s [len - n] := 0X;
  128.       ELSE (* Delete to the end of the string. *)
  129.         s [pos] := 0X;
  130.       END
  131.     END
  132.   END
  133. END Delete;
  134.  
  135.  
  136. PROCEDURE Replace *
  137.   ( source   : ARRAY OF CHAR;
  138.     pos      : INTEGER;
  139.     VAR dest : ARRAY OF CHAR );
  140.  
  141. <*$CopyArrays-*>
  142. BEGIN (* Replace *)
  143.   Delete (dest, pos, Length (source)); Insert (source, pos, dest)
  144. END Replace;
  145.  
  146.  
  147. PROCEDURE Extract *
  148.   ( source   : ARRAY OF CHAR;
  149.     pos, n   : INTEGER;
  150.     VAR dest : ARRAY OF CHAR );
  151.  
  152.   VAR len1, len2 : INTEGER;
  153.  
  154. <*$CopyArrays-*>
  155. BEGIN (* Extract *)
  156.   len2 := 0;
  157.   IF n > 0 THEN
  158.     len1 := Length (source);
  159.     IF (pos < len1) THEN
  160.       len2 := Min ( Min (n, SHORT (LEN (dest)) - 1), len1 - pos);
  161.       SYS.MOVE (SYS.ADR (source [pos]), SYS.ADR (dest), len2);
  162.     END
  163.   END;
  164.   dest [len2] := 0X;
  165. END Extract;
  166.  
  167.  
  168. PROCEDURE Pos *
  169.   ( pattern, s : ARRAY OF CHAR;
  170.     pos        : INTEGER )
  171.   : INTEGER;
  172.  
  173.   VAR
  174.     result, i, len1, len2 : INTEGER;
  175.     found, match : BOOLEAN;
  176.  
  177. <*$CopyArrays-*>
  178. BEGIN (* Pos *)
  179.   result := -1;
  180.   IF pos >= 0 THEN
  181.     len1 := Length (pattern); len2 := Length (s);
  182.     IF (len1 = 0) OR (len2 = 0) OR (pos >= len2) THEN
  183.       result := -1
  184.     ELSE
  185.       found := FALSE;
  186.       WHILE ~found & ((len2 - pos) >= len1) DO
  187.         IF s [pos] = pattern [0] THEN
  188.           match := TRUE; i := 0;
  189.           WHILE match & (i < len1) DO
  190.             IF s [pos + i] = pattern [i] THEN INC (i)
  191.             ELSE match := FALSE
  192.             END
  193.           END;
  194.           found := match
  195.         ELSE
  196.           INC (pos)
  197.         END
  198.       END;
  199.       IF found THEN result := pos END
  200.     END
  201.   END;
  202.   RETURN result
  203. END Pos;
  204.  
  205.  
  206. PROCEDURE Cap *
  207.   ( VAR s : ARRAY OF CHAR );
  208.  
  209.   VAR index : INTEGER; ch : CHAR;
  210.  
  211. BEGIN (* Cap *)
  212.   index := 0; ch := s [0];
  213.   WHILE ch # 0X DO
  214.     s [index] := CAP (ch); INC (index); ch := s [index]
  215.   END
  216. END Cap;
  217.  
  218. END Strings.
  219.